<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Developing Stories</title>
</head>

<body>

<h2 id="writing">Writing Textual Stories</h2>

<p><a href="concepts.html">Behaviour-Driven Development</a>
encourages you to start defining the stories via scenarios that express
the desired behaviour in a textual format, e.g.:</p>
<pre class="brush: bdd">
    Given a stock of symbol STK1 and a threshold of 10.0
    When the stock is traded at 5.0
    Then the alert status should be OFF
</pre>
<p>The textual scenario should use the language of the business
domain and shield away as much as possible the details of the technical
implementation. Also, it should be given a name that is expressive of
the functionality that is being verified, i.e. <b>trader_is_alerted_of_status.story</b>.
</p>
<p>The scenario should use a syntax compatible with the <a
	href="grammar.html">Grammar</a>.</p>


<span class="followup">A story is a collection of scenarios, each
detailing different examples of the behaviour of a given increment of
functionality of the system.</span>

<pre class="brush: bdd">
    Scenario:  trader is not alerted below threshold

    Given a stock of symbol STK1 and a threshold of 10.0
    When the stock is traded at 5.0
    Then the alert status should be OFF

    Scenario:  trader is alerted above threshold

    Given a stock of symbol STK1 and a threshold of 10.0
    When the stock is traded at 11.0
    Then the alert status should be ON
</pre>

<h2 id="mapping">Mapping Textual Scenario Steps to Java Methods via annotations</h2>

<p>JBehave maps textual steps to Java methods via <a
	href="javadoc/core/org/jbehave/core/steps/CandidateSteps.html">CandidateSteps</a>.
The scenario writer need only provide annotated methods that match, by
regex patterns, the textual steps.</p>

<pre class="brush: java">
public class TraderSteps { // look, Ma, I'm a POJO!!
 
    private Stock stock;

    @Given("a stock of symbol $symbol and a threshold of $threshold")
    public void aStock(String symbol, double threshold) {
        stock = new Stock(symbol, threshold);
    }

    @When("the stock is traded at $price")
    public void theStockIsTradedAt(double price) {
        stock.tradeAt(price);
    }

    @Then("the alert status should be $status")
    public void theAlertStatusShouldBe(String status) {
        ensureThat(stock.getStatus().name(), equalTo(status));
    }

}
</pre>

<span class="followup"> The scenario writer can specify the
annotated methods in a POJO, i.e. without needing to extend/implement
any JBehave class/interface. Of course, the Steps instances may inherit
or implement other class/interface as required by the model of the
application under test. </span>

<p>To create instances of <a
	href="javadoc/core/org/jbehave/core/steps/CandidateSteps.html">CandidateSteps</a>
we use an instance of <a
	href="javadoc/core/org/jbehave/core/steps/InjectableStepsFactory.html">InjectableStepsFactory</a>
</p>
<pre class="brush: java">
    Configuration configuration = ... // optional configuration
    InjectableStepsFactory factory = new InstanceStepsFactory(configuration, new TraderSteps(), new BeforeAndAfterSteps());
</pre>
<p>Each step is annotated with one of the <a href="annotations.html">step
annotations</a>, each holding a regex pattern as value. The pattern is used
to match the method in the Steps class with the appropriate parameters.
The simplest default behaviour identifies arguments in the candidate
step by the words prefixed by the <b>$</b> character. More advanced <a
	href="parameter-injection.html">parameter injection</a> mechanisms are
also supported by JBehave.</p>
<p>JBehave execute all the matched steps in the order in which they
are found in the scenario. It is up to the implementor of the Steps
classes to provide the logic to tie together the results of the
execution of each step. This can be done by keeping state member
variables in the Steps class or possibly by using a service API or other
dependency.</p>

<h2 id="configuring">Configuring Java Embeddable classes</h2>

<p>At the heart of the JBehave running of stories lies the <a
	href="javadoc/core/org/jbehave/core/embedder/Embedder.html">Embedder</a>,
which provides an entry point to all of JBehave's functionality that is
embeddable into other launchers, such as IDEs or CLIs. JBehave
complements the Embedder with an <a
	href="javadoc/core/org/jbehave/core/Embeddable.html">Embeddable</a>
which represents a runnable facade to the Embedder.</p>

<span class="followup">JBehave allows many different ways to
configure Embeddable Java classes that allow the parsing and running of textual stories.</span>

<p>JBehave provides two main Embeddable implementations:</p>

<ul>
	<li><a
		href="javadoc/core/org/jbehave/core/ConfigurableEmbedder.html">ConfigurableEmbedder</a>:
	allows the specification of the Configuration and CandidateSteps.</li>
	<li><a
		href="javadoc/core/org/jbehave/core/InjectableEmbedder.html">InjectableEmbedder</a>:
	allows the injection of a fully specified Embedder.</li>
</ul>

<h3>JUnit-enabled Embeddables</h3>

<p><a href="http://junit.org">JUnit</a> is supported out-of-the-box
via several Embeddables implementations:</p>

<ul>
	<li><a href="javadoc/core/org/jbehave/core/junit/JUnitStory.html">JUnitStory</a>:
	provides a one-to-one mapping with the textual story via the <a
		href="javadoc/core/org/jbehave/core/io/StoryPathResolver.html">StoryPathResolver</a>.
	</li>
	<li><a
		href="javadoc/core/org/jbehave/core/junit/JUnitStories.html">JUnitStories</a>:
	provides a many-to-one mapping with the textual story paths explicitly
	specified by overriding the <b>storyPaths()</b> method.</li>
</ul>

<p>In the case of one-to-one mapping, our abstract base TraderStory
would look like:</p>
<script type="syntaxhighlighter" class="brush: java">
<![CDATA[
public abstract class TraderStory extends JUnitStory {

    private final CrossReference xref = new CrossReference();

    public TraderStory() {
        configuredEmbedder().embedderControls().doGenerateViewAfterStories(true).doIgnoreFailureInStories(true)
                .doIgnoreFailureInView(true).useThreads(2).useStoryTimeoutInSecs(60);
        // Uncomment to set meta filter, which can also be set via Ant or Maven
        // configuredEmbedder().useMetaFilters(Arrays.asList("+theme parametrisation"));
    }

    @Override
    public Configuration configuration() {
        Class<? extends Embeddable> embeddableClass = this.getClass();
        Properties viewResources = new Properties();
        viewResources.put("decorateNonHtml", "true");
        // Start from default ParameterConverters instance
        ParameterConverters parameterConverters = new ParameterConverters();
        // factory to allow parameter conversion and loading from external
        // resources (used by StoryParser too)
        ExamplesTableFactory examplesTableFactory = new ExamplesTableFactory(new LocalizedKeywords(),
                new LoadFromClasspath(embeddableClass), parameterConverters);
        // add custom converters
        parameterConverters.addConverters(new DateConverter(new SimpleDateFormat("yyyy-MM-dd")),
                new ExamplesTableConverter(examplesTableFactory));

        return new MostUsefulConfiguration()
                .useStoryControls(new StoryControls().doDryRun(false).doSkipScenariosAfterFailure(false))
                .useStoryLoader(new LoadFromClasspath(embeddableClass))
                .useStoryParser(new RegexStoryParser(examplesTableFactory))
                .useStoryPathResolver(new UnderscoredCamelCaseResolver())
                .useStoryReporterBuilder(
                        new StoryReporterBuilder()
                                .withCodeLocation(CodeLocations.codeLocationFromClass(embeddableClass))
                                .withDefaultFormats().withPathResolver(new ResolveToPackagedName())
                                .withViewResources(viewResources).withFormats(CONSOLE, TXT, HTML, XML)
                                .withFailureTrace(true).withFailureTraceCompression(true).withCrossReference(xref))
                .useParameterConverters(parameterConverters)
                // use '%' instead of '$' to identify parameters
                .useStepPatternParser(new RegexPrefixCapturingPatternParser("%")) 
                .useStepMonitor(xref.getStepMonitor());
    }

    @Override
    public InjectableStepsFactory stepsFactory() {
        return new InstanceStepsFactory(configuration(), new TraderSteps(new TradingService()), new AndSteps(), new MetaParametrisationSteps(),
                new CalendarSteps(), new PriorityMatchingSteps(), new PendingSteps(), new ParametrisedSteps(), new SandpitSteps(),
                new SearchSteps(), new BeforeAfterSteps(), new CompositeSteps(), new CompositeNestedSteps(), new NamedParametersSteps());
    }

}
]]>
</script>

<p>We then extend this base class with a class for each story, e.g.
<code>TraderIsAletedOfStatus.java</code>, which maps to out textual
story in same package.</p>

<p>In the case of many-to-one mapping:</p>

<script type="syntaxhighlighter" class="brush: java">
<![CDATA[
public class TraderStories extends JUnitStories {

    private final CrossReference xref = new CrossReference();

    public TraderStories() {
        configuredEmbedder().embedderControls().doGenerateViewAfterStories(true).doIgnoreFailureInStories(false)
                .doIgnoreFailureInView(true).doVerboseFailures(true).useThreads(2).useStoryTimeoutInSecs(60);
        //configuredEmbedder().useEmbedderControls(new PropertyBasedEmbedderControls());
    }

    @Override
    public Configuration configuration() {
        Class<? extends Embeddable> embeddableClass = this.getClass();
        Properties viewResources = new Properties();
        viewResources.put("decorateNonHtml", "true");
        viewResources.put("reports", "ftl/jbehave-reports-with-totals.ftl");
        // Start from default ParameterConverters instance
        ParameterConverters parameterConverters = new ParameterConverters();
        // factory to allow parameter conversion and loading from external resources (used by StoryParser too)
        ExamplesTableFactory examplesTableFactory = new ExamplesTableFactory(new LocalizedKeywords(), new LoadFromClasspath(embeddableClass), parameterConverters);
        // add custom converters
        parameterConverters.addConverters(new DateConverter(new SimpleDateFormat("yyyy-MM-dd")),
                new ExamplesTableConverter(examplesTableFactory));
        return new MostUsefulConfiguration()
            .useStoryLoader(new LoadFromClasspath(embeddableClass))
            .useStoryParser(new RegexStoryParser(examplesTableFactory)) 
            .useStoryReporterBuilder(new StoryReporterBuilder()
                .withCodeLocation(CodeLocations.codeLocationFromClass(embeddableClass))
                .withDefaultFormats()
                .withViewResources(viewResources)
                .withFormats(CONSOLE, TXT, HTML_TEMPLATE, XML_TEMPLATE)
                .withFailureTrace(true)
                .withFailureTraceCompression(true)                
                .withCrossReference(xref)) 
            .useParameterConverters(parameterConverters)                     
            // use '%' instead of '$' to identify parameters
            .useStepPatternParser(new RegexPrefixCapturingPatternParser(
                            "%")) 
            .useStepMonitor(xref.getStepMonitor());                               
    }

    @Override
    public InjectableStepsFactory stepsFactory() {
        return new InstanceStepsFactory(configuration(), new TraderSteps(new TradingService()), new AndSteps(), new MetaParametrisationSteps(),
                new CalendarSteps(), new PriorityMatchingSteps(), new PendingSteps(), new SandpitSteps(),
                new SearchSteps(), new BeforeAfterSteps(), new CompositeSteps(), new NamedParametersSteps());
    }
    
    @Override
    protected List<String> storyPaths() {
        // Specify story paths as URLs
        String codeLocation = codeLocationFromClass(this.getClass()).getFile();
        return new StoryFinder().findPaths(codeLocation, asList("**/trader_is_alerted_of_status.story",
                "**/traders_can_be_subset.story"), asList(""), "file:" + codeLocation);
    }
        
}
]]>
</script>

<h3>JUnit AnnotatedEmbedderRunner</h3>

<p>JBehave also provides an implementation of JUnit's Runner, <a
	href="javadoc/core/org/jbehave/core/junit/AnnotatedEmbedderRunner.html">AnnotatedEmbedderRunner</a>,
which is runnable via JUnit's <b>@RunWith</b> annotation:</p>

<script type="syntaxhighlighter" class="brush: java">
<![CDATA[
@RunWith(AnnotatedEmbedderRunner.class)
@Configure(storyLoader = MyStoryLoader.class, storyReporterBuilder = MyReportBuilder.class, 
        parameterConverters = { MyDateConverter.class })
@UsingEmbedder(embedder = Embedder.class, generateViewAfterStories = true, ignoreFailureInStories = true, ignoreFailureInView = true)
@UsingSteps(instances = { TraderSteps.class, BeforeAfterSteps.class, AndSteps.class, CalendarSteps.class,
        PriorityMatchingSteps.class, SandpitSteps.class })
public class TraderAnnotatedEmbedder implements Embeddable {

    private Embedder embedder;

    public void useEmbedder(Embedder embedder) {
        this.embedder = embedder;
    }

    @Test
    public void run() {
        embedder.runStoriesAsPaths(new StoryFinder().findPaths(codeLocationFromClass(this.getClass()).getFile(),
                asList("**/*.story"), asList("")));
    }
]]>
</script>

<h3>Integration with other frameworks</h3>

<p>As remarked above, JBehave does not impose any tie-in with any
framework to run stories. It only requires access to the Embedder to run
the stories. The following snippet shows, for example, how to use
SpringJUnit4ClassRunner to compose and inject steps instances and them
the stories:</p>

<script type="syntaxhighlighter" class="brush: java">
<![CDATA[
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "/org/jbehave/examples/trader/spring/steps.xml" })
public class AnnotatedEmbedderWithSpringJUnit4ClassRunner {

    @Autowired
    private TraderSteps traderSteps;

    @Autowired
    private BeforeAfterSteps beforeAndAfterSteps;

    @Test
    public void runStoriesAsPaths() {
        embedder().runStoriesAsPaths(storyPaths());
    }

    @Test
    public void findMatchingCandidateSteps() {
        embedder().reportMatchingStepdocs("When traders are subset to \".*y\" by name");
        embedder().reportMatchingStepdocs("Given a step that is not matched");
    }

    private Embedder embedder() {
        Embedder embedder = new ClasspathTraderEmbedder();
        embedder.useStepsFactory(new InstanceStepsFactory(embedder.configuration(), traderSteps, beforeAndAfterSteps));
        return embedder;
    }

    protected List<String> storyPaths() {
        StoryFinder finder = new StoryFinder();
        return finder.findPaths(codeLocationFromClass(this.getClass()).getFile(), asList("**/*.story"), asList(""));
    }

}
]]>
</script>

<h2>What Next?</h2>

<span class="followup">JBehave provides fully annotatation-based
support for specifying <a href="configuration.html">configuration</a>
and <a href="dependency-injection.html">dependency injection</a>. The <a
	href="running-stories.html">running stories</a> will go into more
details of the different ways to run stories. Or if you want to learn
more about JBehave's step matching mechanism, you'll want to explore the
concept of <a href="candidate-steps.html">candidate steps</a> in more
detail. </span>

<div class="clear">
<hr />
</div>

</body>
</html>
